using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx;
using HarmonyLib;
using Hearthstone;
using Hearthstone.Progression;
using PegasusLettuce;
using PegasusShared;
using PegasusUtil;
using UnityEngine;
using System.Threading;

namespace Mercenary
{
    public static class UtilsTeam
    {
        public static long m_teamId=-1;
        public static string m_teamName="AutoAi";

        //根据策略选择佣兵和装备
        public static void UpdateTeam()
        {
            //需要根据实际情况判断是否需要更新队伍
            UtilsLog.Log("[队伍编辑]");

            if (UtilsGui.modeConf.m_id == UiItemConst.模式_自动佣兵任务.m_id)
            {
                bool bDismiss=false;
                foreach (Task task in TaskUtils.GetTaskList())
                {
                    int Progress=0;
                    NetCache.NetCacheMercenariesVillageVisitorInfo netObject =
                        NetCache.Get().GetNetObject<NetCache.NetCacheMercenariesVillageVisitorInfo>();
                    for (int i = netObject.VisitorStates.Count-1 ; i >= 0; --i)
                    {
                        if(task.Id==netObject.VisitorStates[i].ActiveTaskState.TaskId)
                        {
                            Progress=netObject.VisitorStates[i].ActiveTaskState.Progress;
                            break;
                        }
                    }
                    UtilsLog.Log(string.Format("任务={0} 进度={1} 已持续={2}s",
                        task.Id, Progress, (TaskUtils.Current() - task.StartAt)));
                    if (Progress==0 && (TaskUtils.Current() - task.StartAt > (long)7200))
                    {
                        bDismiss=true;
                        UtilsLog.Log(string.Format("任务={0} 2小时内进度为0，放弃", task.Id));
                        TaskUtils.DismissTask(task.Id);
                    }
                }
                if(bDismiss) TaskUtils.UpdateMercTask();
                UtilsLog.Log(string.Format("[状态] 更新任务状态完成"));
                AutoChangeTeam();
            }
            else if (UtilsGui.modeConf.m_id == UiItemConst.模式_自动主线任务.m_id ||
                     UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
            {
                AutoChangeTeam();
            }

            /*
            //自动创建队伍
            LettuceTeam lettuceTeam = null;
            while (null == (lettuceTeam = CollectionManager.Get().GetTeams().Find(
                (LettuceTeam t) => t.Name.Equals(m_teamName))))
            {
                CollectionManager.Get().SendCreateTeam(m_teamName,
                    PegasusLettuce.LettuceTeam.Type.TYPE_SOLO);
                Thread.Sleep(2000);
            }

            //更新佣兵队列
            UtilsStra.UpdateMercList();

            //先移除，后续考虑判断有相同的则不移除
            List<LettuceMercenary> mercs = lettuceTeam.GetMercs();
            foreach (LettuceMercenary lettuceMercenary in mercs)
            {
                lettuceTeam.RemoveMerc(lettuceMercenary.ID);
            }

            //再添加
            int countMax=6;//后续可以根据策略调整
            foreach (MercCard merc in UtilsStra.GetStrategy(
                UtilsGui.strategyConf.m_name).GetMercList())
            {
                LettuceMercenary mercenary = CollectionManager.Get().
                    GetMercenary((long)merc.m_id, false, true);
                if(lettuceTeam.GetMercCount()>=countMax) break;
                else if (mercenary != null && mercenary.m_owned &&
                    !lettuceTeam.IsMercInTeam(merc.m_id, true))
                {
                    UtilsMerc.SlotMercEquip(merc.m_id, merc.m_slotEquip);
                    lettuceTeam.AddMerc(mercenary, -1, null);
                }
            }
            lettuceTeam.SendChanges();
            */

            m_teamId = -1;
            LettuceTeam lettuceTeam = CollectionManager.Get().GetTeams().Find(
                (LettuceTeam t) => t.Name.Equals(m_teamName));
            if (lettuceTeam != null) m_teamId = lettuceTeam.ID;
        }

        //选择队伍
        public static void SelectTeam()
        {
            UtilsLog.Log("[队伍选择]");
            LettuceVillageDisplay.LettuceSceneTransitionPayload lettuceSceneTransitionPayload =
                new LettuceVillageDisplay.LettuceSceneTransitionPayload();
            LettuceBountyDbfRecord record = GameDbf.LettuceBounty.
                GetRecord(UtilsMap.m_currMap.m_id);
            lettuceSceneTransitionPayload.m_TeamId = m_teamId;
            lettuceSceneTransitionPayload.m_SelectedBounty = record;
            lettuceSceneTransitionPayload.m_SelectedBountySet = record.BountySetRecord;
            lettuceSceneTransitionPayload.m_DifficultyMode = (Assets.LettuceBounty.MercenariesBountyDifficulty)(record.Heroic?2:1);
            SceneMgr.Get().SetNextMode(SceneMgr.Mode.LETTUCE_MAP,
                SceneMgr.TransitionHandlerType.CURRENT_SCENE, null, lettuceSceneTransitionPayload);
        }

        public static void AutoChangeTeam()
        {
            LettuceTeam lettuceTeam = null;
            List<LettuceMercenary> mercenaries = CollectionManager.Get().FindMercenaries(
                null, new bool?(true), null, null, null,true).m_mercenaries;

            //自动创建队伍
            /*while (null == (lettuceTeam = CollectionManager.Get().GetTeams().Find(
                (LettuceTeam t) => t.Name.Equals(m_teamName))))
            {
                CollectionManager.Get().SendCreateTeam(m_teamName,
                    PegasusLettuce.LettuceTeam.Type.TYPE_SOLO);
                Thread.Sleep(2000);
            }*/

            if (null== (lettuceTeam=CollectionManager.Get().GetTeams().Find(
                (LettuceTeam t) => t.Name.Equals(m_teamName)))) return;

            //先移除，后续考虑判断有相同的则不移除
            List<LettuceMercenary> mercs = lettuceTeam.GetMercs();
            foreach (LettuceMercenary lettuceMercenary in mercs)
            {
                lettuceTeam.RemoveMerc(lettuceMercenary.ID);
            }

            if (lettuceTeam.GetMercCount() < 6)
			{
				// 先考虑全自动模式
				if (UtilsGui.modeConf.m_id == UiItemConst.模式_自动佣兵任务.m_id)
				{
					foreach (Task task in TaskUtils.GetTaskList())
                    {
                        foreach (MercenaryEntity mercenaryEntity in task.Mercenaries)
                        {
                            LettuceMercenary mercenary = CollectionManager.Get().GetMercenary(
                                (long)mercenaryEntity.ID, false, true);
                            if (mercenary != null && mercenary.m_owned && !lettuceTeam.IsMercInTeam(
                                mercenaryEntity.ID, true))
                            {
                                UtilsMerc.SlotMercEquip(mercenaryEntity.ID, mercenaryEntity.Equipment);
                                lettuceTeam.AddMerc(mercenary, -1, null);
                                if (lettuceTeam.GetMercCount() == 6)
                                {
                                    break;
                                }
                            }
                        }
                        if (lettuceTeam.GetMercCount() == 6)
                        {
                            break;
                        }
                    }
				}
                else if (UtilsGui.modeConf.m_id == UiItemConst.模式_自动主线任务.m_id ||
                         UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
				{
					UtilsLog.Log("[队伍编辑] 解锁装备/主线任务");
					UtilsMap.InitMap();
					int mapId = UtilsMap.m_currMap.m_id;
					if (true) // 核心人数 = 0 ，玩家使用预设卡组，
					{
						// 自然队
						if (MercConst.Nature_MapID.Contains(mapId))
						{
							foreach (int num2 in MercConst.Nature)
							{
                                UtilsMerc.SlotMercEquip(num2, MercConst.MercEquipID[num2]);
								LettuceMercenary mercenary2 = UtilsMerc.GetMercenaryFromId(num2);
								if (!lettuceTeam.IsMercInTeam(num2, true)
									&& !mercenary2.IsReadyForCrafting()
									&& mercenary2.m_owned)
								{
									lettuceTeam.AddMerc(mercenary2, -1, null);
									UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，解锁装备/主线任务",
										mercenary2.m_mercName));
									if (lettuceTeam.GetMercCount() == 5 &&
                                        UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
									{
										break;
									}
								}
							}
						}
						// 海盗蛇
						else if (MercConst.Piratesnake_MapID.Contains(mapId))
						{
							foreach (int num2 in MercConst.Piratesnake)
							{
                                UtilsMerc.SlotMercEquip(num2, MercConst.MercEquipID[num2]);
								LettuceMercenary mercenary2 = UtilsMerc.GetMercenaryFromId(num2);
								if (!lettuceTeam.IsMercInTeam(num2, true)
									&& !mercenary2.IsReadyForCrafting()
									&& mercenary2.m_owned)
								{
									lettuceTeam.AddMerc(mercenary2, -1, null);
									UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，解锁装备/主线任务",
										mercenary2.m_mercName));
                                    if (lettuceTeam.GetMercCount() == 5 &&
                                        UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
									{
										break;
									}
								}
							}
						}
                        //火焰刺杀
                        else if (MercConst.FireKill_MapID.Contains(mapId))
                        {
                            foreach (int num2 in MercConst.FireKill)
                            {
                                UtilsMerc.SlotMercEquip(num2, MercConst.MercEquipID[num2]);
                                LettuceMercenary mercenary2 = UtilsMerc.GetMercenaryFromId(num2);
                                if (!lettuceTeam.IsMercInTeam(num2, true)
                                    && !mercenary2.IsReadyForCrafting()
                                    && mercenary2.m_owned)
                                {
                                    lettuceTeam.AddMerc(mercenary2, -1, null);
                                    UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，解锁装备/主线任务",
                                        mercenary2.m_mercName));
                                    if (lettuceTeam.GetMercCount() == 5 &&
                                        UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        // 冰队
                        else if (MercConst.SnowTeam_MapID.Contains(mapId))
						{
							foreach (int num2 in MercConst.Piratesnake)
							{
								if (num2 != MercConst.瓦尔登_晨拥.m_id)
									UtilsMerc.SlotMercEquip(num2, MercConst.MercEquipID[num2]);
								else
									UtilsMerc.SlotMercEquip(num2, 1);
								LettuceMercenary mercenary2 = UtilsMerc.GetMercenaryFromId(num2);
								if (!lettuceTeam.IsMercInTeam(num2, true)
									&& !mercenary2.IsReadyForCrafting()
									&& mercenary2.m_owned)
								{
									lettuceTeam.AddMerc(mercenary2, -1, null);
									UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，解锁装备/主线任务",
										mercenary2.m_mercName));
									if (lettuceTeam.GetMercCount() == 5 &&
                                        UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
									{
										break;
									}
								}
							}
						}
						// 冰火队
						else
						{
							foreach (int num2 in MercConst.SnowFire)
							{
								UtilsMerc.SlotMercEquip(num2, MercConst.MercEquipID[num2]);
								LettuceMercenary mercenary2 = UtilsMerc.GetMercenaryFromId(num2);
								if (!lettuceTeam.IsMercInTeam(num2, true)
									&& !mercenary2.IsReadyForCrafting()
									&& mercenary2.m_owned)
								{
									lettuceTeam.AddMerc(mercenary2, -1, null);
									UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，解锁装备/主线任务",
										mercenary2.m_mercName));
									if (lettuceTeam.GetMercCount() == 5 &&
                                        UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
									{
										break;
									}
								}
							}
						}
					}

					if (UtilsMap.unlockMercID.Count > 0 && UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id) // 存在待解锁的佣兵
					{
						LettuceMercenary mercBoss = UtilsMerc.GetMercenaryFromId(UtilsMap.unlockMercID[0]);
						lettuceTeam.AddMerc(mercBoss, -1, null);
						UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，解锁装备", mercBoss.m_mercName));
					}
				}

				if (lettuceTeam.GetMercCount() < 6)
				{
					foreach (LettuceMercenary lettuceMercenary2 in mercenaries)
					{
						if (!lettuceTeam.IsMercInTeam(lettuceMercenary2.ID, true)
							&& !lettuceMercenary2.IsReadyForCrafting()
							&& !lettuceMercenary2.IsMaxLevel())
						{
							lettuceTeam.AddMerc(lettuceMercenary2, -1, null);
							UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，因为未30级",
								lettuceMercenary2.m_mercName));
							if (lettuceTeam.GetMercCount() == 6)
							{
								break;
							}
						}
					}
				}
				if (lettuceTeam.GetMercCount() < 6)
				{
					foreach (int num2 in MercConst.SnowFire)
					{
						LettuceMercenary mercenary2 = UtilsMerc.GetMercenaryFromId(num2);
						if (!lettuceTeam.IsMercInTeam(num2, true)
							&& !mercenary2.IsReadyForCrafting()
							&& CalcMercenaryCoinNeed(mercenary2) != 8192
							&& mercenary2.m_owned)
						{
							lettuceTeam.AddMerc(mercenary2, -1, null);
							UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，因为+1+5优先级设置高",
								mercenary2.m_mercName));
							if (lettuceTeam.GetMercCount() == 6)
							{
								break;
							}
						}
					}
				}

				if (lettuceTeam.GetMercCount() < 6)
				{
					foreach (LettuceMercenary lettuceMercenary3 in mercenaries)
					{
						if (!lettuceTeam.IsMercInTeam(lettuceMercenary3.ID, true)
							&& !lettuceMercenary3.IsReadyForCrafting()
							&& CalcMercenaryCoinNeed(lettuceMercenary3) != 8192
							&& !MercConst.Ignore.Contains(lettuceMercenary3.ID))
						{
							lettuceTeam.AddMerc(lettuceMercenary3, -1, null);
							UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，碎片不够+1+5",
								lettuceMercenary3.m_mercName));
							if (lettuceTeam.GetMercCount() == 6)
							{
								break;
							}
						}
					}
				}
				if (lettuceTeam.GetMercCount() < 6)
				{
					foreach (LettuceMercenary lettuceMercenary4 in mercenaries)
					{
						if (!lettuceTeam.IsMercInTeam(lettuceMercenary4.ID, true) &&
                            !lettuceMercenary4.IsReadyForCrafting())
						{
							lettuceTeam.AddMerc(lettuceMercenary4, -1, null);
							UtilsLog.Log(string.Format("[队伍编辑] 添加[{0}]，满级优先级设置低",
								lettuceMercenary4.m_mercName));
							if (lettuceTeam.GetMercCount() == 6)
							{
								break;
							}
						}
					}
				}
				lettuceTeam.SendChanges();
			}
        }

        public static long CalcMercenaryCoinNeed(LettuceMercenary merc)
        {
            long coinNeed = 0;
            if (!merc.m_owned)
            {
                coinNeed = merc.GetCraftingCost() - merc.m_currencyAmount;
                return (coinNeed > 0) ? coinNeed : 4096;
            }

            foreach (var ability in merc.m_abilityList)
            {
                if (ability.GetNextUpgradeCost() <= 0)
                {
                    continue;
                }
                int tier = ability.GetNextTier() - 1;
                switch (tier)
                {
                    case 1:
                        coinNeed += 50 + 125 + 150 + 150;
                        break;
                    case 2:
                        coinNeed += 125 + 150 + 150;
                        break;
                    case 3:
                        coinNeed += 150 + 150; ;
                        break;
                    case 4:
                        coinNeed += 150;
                        break;
                    case 5:
                        coinNeed += 0;
                        break;
                }
            }
            foreach (var equipment in merc.m_equipmentList)
            {
                if (equipment.GetNextUpgradeCost() <= 0)
                {
                    continue;
                }
                int tier = equipment.GetNextTier() - 1;
                switch (tier)
                {
                    case 1:
                        coinNeed += 100 + 150 + 175;
                        break;
                    case 2:
                        coinNeed += 150 + 175;
                        break;
                    case 3:
                        coinNeed += 175; ;
                        break;
                    case 4:
                        coinNeed += 0;
                        break;
                }
            }
            coinNeed -= merc.m_currencyAmount;
            return (coinNeed > 0) ? coinNeed : 8192;
        }
    }
}
